package 基本线程机制.新类库中的构件;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/*
 DelayQueue 延期队列，队列的内容必须继承Delay接口，并实现方法。每次都会获取时间到的的内容。
 */
public class DelayQueueDemo {
	public static void main(String[] args) {
		Random random=new Random(47);
		ExecutorService exec=Executors.newCachedThreadPool();
		DelayQueue<DelayedTask> queue=new DelayQueue<>();//定时执行的队列
		for(int i=0;i<20;i++){
			queue.put(new DelayedTask(random.nextInt(5000)));
		}
		queue.add(new DelayedTask.EndSentinel(5000, exec));//增加第20个到队列中
		exec.execute(new DelayedTaskCoonsumer(queue));
	}
}
class DelayedTask implements Runnable,Delayed{//Delayed,[dɪ'led],到时间才能取出的队列
	private static int counter=0;
	private final int id=counter++;//DelayedTask的id，也就是顺序
	private final int delta;//定时的时间
	private final long trigger;//触发时间
	protected static List<DelayedTask> sequence=new ArrayList<>();//保存DelayedTask创建时候的顺序
	
	public DelayedTask(int delayInMilliseconds){
		delta=delayInMilliseconds;
		trigger=System.nanoTime()+TimeUnit.NANOSECONDS.convert(delta, TimeUnit.MILLISECONDS);
		sequence.add(this);
	}
	public long getDelay(TimeUnit unit) {//获取到期时间   Delayed接口
		return unit.convert(trigger-System.nanoTime(), TimeUnit.NANOSECONDS);
	}
	public int compareTo(Delayed arg) {//比较  Comparable接口
		DelayedTask that=(DelayedTask)arg; 
		if(trigger<that.trigger){return -1;}   //小于返回-1，
		if(trigger>that.trigger){return 1;}  //如果前者大于后者，返回1
		return 0; 	//等于返回0
	}
	public void run() {
		System.out.print(this+" ");
	}
	public String toString(){
		return String.format("[%1$-4d]", delta)+" Task "+id;
	}
	public String summary(){//获取摘要，id和到期时间
		return "("+id+":"+delta+")";
	}
	public static class EndSentinel extends DelayedTask{
		private ExecutorService exec;
		public EndSentinel(int delay,ExecutorService e){
			super(delay);
			exec=e;
		}
		public void run(){
			for(DelayedTask pt:DelayedTask.sequence){
				System.out.print(pt.summary()+" ");//获取内容
			}
			System.out.println(this+" Calling shutdownNow()");
			exec.shutdownNow();
		}
	}
}
class DelayedTaskCoonsumer implements Runnable{
	private DelayQueue<DelayedTask> q;
	public DelayedTaskCoonsumer(DelayQueue<DelayedTask> q){
		this.q=q;
	}
	public void run(){
		try{
			while(!Thread.interrupted()){
				q.take().run();
			}
		}
		catch (InterruptedException e) {
			
		}
		System.out.println("Finished DelayedTaskConsumer");
	}
}